// testing of the dominion.c updateCoins() function

#include <stdio.h>
#include <stdlib.h>
#include "dominion.h"
#include "dominion_helpers.h"
#include "rngs.h"

#define MAX_CARD treasure_map

typedef struct gameState gameState;

//print the results of the testing
void print_results(int a, int b){
    double results = ((double)a) / b;
    printf("---------------------\n");
    printf("updateCoins() -- %.f%% of test cases passed (%d/%d)\n", (results*100), a, b);
}

//sets all the values in the game struct to 0
void init_gamestate(struct gameState *g){
    int i;
    for(i = 0; i < sizeof(struct gameState); i++){
    	((char *)g)[i] = 0;
	}
}

int getValue(int card){
	if(card == copper){
		return 1;
	}
	else if(card == silver){
		return 2;
	}
	else if(card == gold){
		return 3;
	}
	return 0;
}

int main(int argc, char **argv) {
    int i, j;
    int handCount, bonus, player;
    int expected_result, result;
    int good_test, bad_test;
	int randomSeed, test_count;
    gameState g;
   
    if(argc != 3){
            printf("Usage: unittest1 [seed] [number of tests]\n");
            return(0);
    }
   
    //initialize vars
    randomSeed = atoi(argv[1]);
    test_count = atoi(argv[2]);
    if(test_count < 0){
            printf("Please provide a positive integer for [number of tests]\n");
            return(0);
    }
    good_test = bad_test = 0;
   
    // set up random number
    SelectStream(1);
    PutSeed((long)randomSeed);
    
    for(i = 0; i<test_count; i++){
    	//create random inputs
    	init_gamestate(&g);
    	player = (int)(Random()*3)+1; //random player number
    	handCount = (int)(Random()*5); //random hand size
		g.handCount[player] = handCount;
		expected_result = 0;
    	//create random hands for the player
    	for(j=0; j < handCount; j++){
    		g.hand[player][j] = (int)(Random()*MAX_CARD);
    		//add the value of the new card to our expected value
    		expected_result += getValue(g.hand[player][j]);
    	}
    	bonus = (int)(Random()*5); //random bonus amount
    	expected_result += bonus;
    	
    	//call the function
    	updateCoins(player, &g, bonus);
    	
    	//check the results
    	if(g.coins != expected_result){
    		printf("Error: wrong number of coins!\n");
    		printf("\texpected %d(%d) coins, but got %d\n", expected_result,bonus, g.coins);
			for(j=0; j<handCount; j++){
				printf("%d ", g.hand[player][j]);
			}
			printf("\n");
    		bad_test++;
    	}
    	else{
    		good_test++;
    	}
    }

    //output the results
    print_results(good_test, test_count);
   
    return 0;
}
